/*
 *  /linux-3.0.8/drivers/media/video/gt2440_cam.h
*/

#ifndef __GT2440_VCAM_H
#define __GT2440_VCAM_H


/* plat data structure */
struct gt2440_cam_platdata{
	struct i2c_board_info i2c_board_info;
	
	unsigned long clock_frequency;
	enum v4l2_mbus_type mbus_type;
	u16 i2c_bus_num;
	u16 flags;
	u8 use_field;
	
	int (*gpio_get)(void);
	int (*gpio_put)(void);
};



/* driver data structure */

#define VP_CODEC	0
#define VP_PREVIEW	1
#define CAM_VP_NUM	2
enum {
	CLK_GATE,
	CLK_CAM,
	CLK_MAX_NUM,
};
enum img_fmt {
	IMG_FMT_RGB565 = 0x0010,
	IMG_FMT_RGB666,
	IMG_FMT_XRGB8888,
	IMG_FMT_YCBCR420 = 0x0020,
	IMG_FMT_YCRCB420,
	IMG_FMT_YCBCR422P,
	IMG_FMT_YCBYCR422 = 0x0040,
	IMG_FMT_YCRYCB422,
	IMG_FMT_CBYCRY422,
	IMG_FMT_CRYCBY422,
};
struct gt2440_cam_sensor {
		struct v4l2_subdev	*v4l2_sub;
		short			power_count;
		short			stream_count;
} ;
struct gt2440_cam_scaler {
	u8 scaleup_h;
	u8 scaleup_v;
	u8 copy;
	u8 enable;
	u32 h_shift;
	u32 v_shift;
	u32 pre_h_ratio;
	u32 pre_v_ratio;
	u32 pre_dst_width;
	u32 pre_dst_height;
	u32 main_h_ratio;
	u32 main_v_ratio;
};
struct gt2440_cam_fmt {
	char *name;
	u32 fourcc;
	u32 color;
	u16 colplanes;
	u16 flags;
	u8 depth;
	u8 ybpp;
};
struct gt2440_cam_dma_offset {
	int	initial;
	int	line;
};
struct gt2440_cam_frame {
	u16 f_width;
	u16 f_height;
	struct v4l2_rect rect;
	struct gt2440_cam_dma_offset dma_offset;
};
struct gt2440_cam_vp {
	wait_queue_head_t	irq_queue;
	/*do not use the media_pad, i hate it. */
	//struct media_pad	pad;
	struct video_device	video_dev;
	struct v4l2_ctrl_handler ctrl_handler;
	struct gt2440_cam_scaler	scaler;
	struct gt2440_cam_frame	out_frame;
	
	struct vb2_queue	vb2_q;
	struct list_head	pending_buf_q;
	struct list_head	active_buf_q;

	const struct gt2440_cam_fmt	*out_fmt;
	
	struct gt2440_cam_info	*info;
	struct v4l2_fh		*owner;
	
	unsigned int		active_buffers;
	unsigned int		buf_index;
	unsigned int		frame_sequence;
	unsigned int		reqbufs_count;
	unsigned int		payload;
	unsigned int		state;
	unsigned int		irq;
	unsigned int		offset;
	
	u16			fmt_flags;
	u8			id;
	u8			rotation;
	u8			hflip;
	u8			vflip;
};

struct gt2440_cam_info{
	/*do not use the media_device, i hate it. */
	//struct media_device		media_dev;
	//struct v4l2_subdev		v4l2_sub;
	
	struct v4l2_device		v4l2_dev;

	struct v4l2_ctrl_handler	ctrl_handler;
	struct v4l2_mbus_framefmt	mbus_framefmt;
	struct v4l2_rect		rect;
	struct gt2440_cam_sensor 		sensor;
	/*do not use the media_pad, i hate it. */
	//struct media_pad		pads[CAMIF_SD_PADS_NUM];
	
	struct gt2440_cam_vp	vp[CAM_VP_NUM]; /* video path */
	
	struct media_pipeline		*pipeline;
	struct v4l2_ctrl		*ctrl_test_pattern;
	
	struct v4l2_ctrl		*ctrl_colorfx;
	struct v4l2_ctrl		*ctrl_colorfx_cbcr;
	
	struct vb2_alloc_ctx		*alloc_ctx;

	const struct gt2440_cam_variant	 *variant;
	struct gt2440_cam_platdata	*pdata;
	
	struct device		*dev;
	struct clk			*clk[CLK_MAX_NUM];
	struct resource 	*res;
	void __iomem		*regs;
	
	int				stream_count;
	u8				test_pattern;
	u8				colorfx;
	u8				colorfx_cb;
	u8				colorfx_cr;
	
	struct mutex			w_mutex;
	
	struct mutex			mutex;
	spinlock_t			lock;
};



/***** buffer data structure *****/
struct gt2440_cam_addr {
	dma_addr_t y;
	dma_addr_t cb;
	dma_addr_t cr;
};
struct gt2440_cam_buffer {
	struct vb2_buffer vb2_b;
	struct list_head list;
	struct gt2440_cam_addr paddr;
	unsigned int index;
};



/***** help data structure *****/
struct gt2440_cam_pix_limits {
	u16 win_hor_offset_align;
};
struct gt2440_cam_vp_pix_limits {
	u16 max_out_width;
	u16 max_sc_out_width;
	u16 out_width_align;
	u16 max_height;
	u8 min_out_width;
	u16 out_hor_offset_align;
};
struct gt2440_cam_variant {
	struct gt2440_cam_vp_pix_limits vp_pix_limits[2];
	struct gt2440_cam_pix_limits pix_limits;
	u8 has_img_effect;
	unsigned int vp_offset;
};


#define GT2440_PA_CAMIF   (0x4F000000)
#define GT2440_SZ_CAMIF   SZ_1M
#define GT2440_CAM_REG_CISRCFMT			0x00
#define  CISRCFMT_ITU601_8BIT			(1 << 31)
#define  CISRCFMT_ITU656_8BIT			(0 << 31)
#define  CISRCFMT_ORDER422_YCBYCR		(0 << 14)
#define  CISRCFMT_ORDER422_YCRYCB		(1 << 14)
#define  CISRCFMT_ORDER422_CBYCRY		(2 << 14)
#define  CISRCFMT_ORDER422_CRYCBY		(3 << 14)
#define  CISRCFMT_ORDER422_MASK			(3 << 14)
#define  CISRCFMT_SIZE_CAM_MASK			(0x1fff << 16 | 0x1fff)

/* Window offset */
#define GT2440_CAM_REG_CIWDOFST			0x04
#define  CIWDOFST_WINOFSEN			(1 << 31)
#define  CIWDOFST_CLROVCOFIY			(1 << 30)
#define  CIWDOFST_CLROVRLB_PR			(1 << 28)
/* #define  CIWDOFST_CLROVPRFIY			(1 << 27) */
#define  CIWDOFST_CLROVCOFICB			(1 << 15)
#define  CIWDOFST_CLROVCOFICR			(1 << 14)
#define  CIWDOFST_CLROVPRFICB			(1 << 13)
#define  CIWDOFST_CLROVPRFICR			(1 << 12)
#define  CIWDOFST_OFST_MASK			(0x7ff << 16 | 0x7ff)

/* Window offset 2 */
#define GT2440_CAM_REG_CIWDOFST2			0x14
#define  CIWDOFST2_OFST2_MASK			(0xfff << 16 | 0xfff)

/* Global control */
#define GT2440_CAM_REG_CIGCTRL			0x08
#define  CIGCTRL_SWRST				(1 << 31)
#define  CIGCTRL_CAMRST				(1 << 30)
#define  CIGCTRL_TESTPATTERN_NORMAL		(0 << 27)
#define  CIGCTRL_TESTPATTERN_COLOR_BAR		(1 << 27)
#define  CIGCTRL_TESTPATTERN_HOR_INC		(2 << 27)
#define  CIGCTRL_TESTPATTERN_VER_INC		(3 << 27)
#define  CIGCTRL_TESTPATTERN_MASK		(3 << 27)
#define  CIGCTRL_INVPOLPCLK			(1 << 26)
#define  CIGCTRL_INVPOLVSYNC			(1 << 25)
#define  CIGCTRL_INVPOLHREF			(1 << 24)
#define  CIGCTRL_IRQ_OVFEN			(1 << 22)
#define  CIGCTRL_HREF_MASK			(1 << 21)
#define  CIGCTRL_IRQ_LEVEL			(1 << 20)
/* IRQ_CLR_C, IRQ_CLR_P */
#define  CIGCTRL_IRQ_CLR(id)			(1 << (19 - (id)))
#define  CIGCTRL_FIELDMODE			(1 << 2)
#define  CIGCTRL_INVPOLFIELD			(1 << 1)
#define  CIGCTRL_CAM_INTERLACE			(1 << 0)

/* Y DMA output frame start address. n = 0..3. */
#define GT2440_CAM_REG_CIYSA(id, n)		(0x18 + (id) * 0x54 + (n) * 4)
/* Cb plane output DMA start address. n = 0..3. Only codec path. */
#define GT2440_CAM_REG_CICBSA(id, n)		(0x28 + (id) * 0x54 + (n) * 4)
/* Cr plane output DMA start address. n = 0..3. Only codec path. */
#define GT2440_CAM_REG_CICRSA(id, n)		(0x38 + (id) * 0x54 + (n) * 4)

/* CICOTRGFMT, CIPRTRGFMT - Target format */
#define GT2440_CAM_REG_CITRGFMT(id, _offs)	(0x48 + (id) * (0x34 + (_offs)))
#define  CITRGFMT_IN422				(1 << 31) /* only for s3c24xx */
#define  CITRGFMT_OUT422			(1 << 30) /* only for s3c24xx */
#define  CITRGFMT_OUTFORMAT_YCBCR420		(0 << 29) /* only for s3c6410 */
#define  CITRGFMT_OUTFORMAT_YCBCR422		(1 << 29) /* only for s3c6410 */
#define  CITRGFMT_OUTFORMAT_YCBCR422I		(2 << 29) /* only for s3c6410 */
#define  CITRGFMT_OUTFORMAT_RGB			(3 << 29) /* only for s3c6410 */
#define  CITRGFMT_OUTFORMAT_MASK		(3 << 29) /* only for s3c6410 */
#define  CITRGFMT_TARGETHSIZE(x)		((x) << 16)
#define  CITRGFMT_FLIP_NORMAL			(0 << 14)
#define  CITRGFMT_FLIP_X_MIRROR			(1 << 14)
#define  CITRGFMT_FLIP_Y_MIRROR			(2 << 14)
#define  CITRGFMT_FLIP_180			(3 << 14)
#define  CITRGFMT_FLIP_MASK			(3 << 14)
/* Preview path only */
#define  CITRGFMT_ROT90_PR			(1 << 13)
#define  CITRGFMT_TARGETVSIZE(x)		((x) << 0)
#define  CITRGFMT_TARGETSIZE_MASK		((0x1fff << 16) | 0x1fff)

/* CICOCTRL, CIPRCTRL. Output DMA control. */
#define GT2440_CAM_REG_CICTRL(id, _offs)		(0x4c + (id) * (0x34 + (_offs)))
#define  CICTRL_BURST_MASK			(0xfffff << 4)
/* xBURSTn - 5-bits width */
#define  CICTRL_YBURST1(x)			((x) << 19)
#define  CICTRL_YBURST2(x)			((x) << 14)
#define  CICTRL_RGBBURST1(x)			((x) << 19)
#define  CICTRL_RGBBURST2(x)			((x) << 14)
#define  CICTRL_CBURST1(x)			((x) << 9)
#define  CICTRL_CBURST2(x)			((x) << 4)
#define  CICTRL_LASTIRQ_ENABLE			(1 << 2)
#define  CICTRL_ORDER422_MASK			(3 << 0)

/* CICOSCPRERATIO, CIPRSCPRERATIO. Pre-scaler control 1. */
#define GT2440_CAM_REG_CISCPRERATIO(id, _offs)	(0x50 + (id) * (0x34 + (_offs)))

/* CICOSCPREDST, CIPRSCPREDST. Pre-scaler control 2. */
#define GT2440_CAM_REG_CISCPREDST(id, _offs)	(0x54 + (id) * (0x34 + (_offs)))

/* CICOSCCTRL, CIPRSCCTRL. Main scaler control. */
#define GT2440_CAM_REG_CISCCTRL(id, _offs)	(0x58 + (id) * (0x34 + (_offs)))
#define  CISCCTRL_SCALERBYPASS			(1 << 31)
/* s3c244x preview path only, s3c64xx both */
#define  CIPRSCCTRL_SAMPLE			(1 << 31)
/* 0 - 16-bit RGB, 1 - 24-bit RGB */
#define  CIPRSCCTRL_RGB_FORMAT_24BIT		(1 << 30) /* only for s3c244x */
#define  CIPRSCCTRL_SCALEUP_H			(1 << 29) /* only for s3c244x */
#define  CIPRSCCTRL_SCALEUP_V			(1 << 28) /* only for s3c244x */
/* s3c64xx */
#define  CISCCTRL_SCALEUP_H			(1 << 30)
#define  CISCCTRL_SCALEUP_V			(1 << 29)
#define  CISCCTRL_SCALEUP_MASK			(0x3 << 29)
#define  CISCCTRL_CSCR2Y_WIDE			(1 << 28)
#define  CISCCTRL_CSCY2R_WIDE			(1 << 27)
#define  CISCCTRL_LCDPATHEN_FIFO		(1 << 26)
#define  CISCCTRL_INTERLACE			(1 << 25)
#define  CISCCTRL_SCALERSTART			(1 << 15)
#define  CISCCTRL_INRGB_FMT_RGB565		(0 << 13)
#define  CISCCTRL_INRGB_FMT_RGB666		(1 << 13)
#define  CISCCTRL_INRGB_FMT_RGB888		(2 << 13)
#define  CISCCTRL_INRGB_FMT_MASK		(3 << 13)
#define  CISCCTRL_OUTRGB_FMT_RGB565		(0 << 11)
#define  CISCCTRL_OUTRGB_FMT_RGB666		(1 << 11)
#define  CISCCTRL_OUTRGB_FMT_RGB888		(2 << 11)
#define  CISCCTRL_OUTRGB_FMT_MASK		(3 << 11)
#define  CISCCTRL_EXTRGB_EXTENSION		(1 << 10)
#define  CISCCTRL_ONE2ONE			(1 << 9)
#define  CISCCTRL_MAIN_RATIO_MASK		(0x1ff << 16 | 0x1ff)

/* CICOTAREA, CIPRTAREA. Target area for DMA (Hsize x Vsize). */
#define GT2440_CAM_REG_CITAREA(id, _offs)	(0x5c + (id) * (0x34 + (_offs)))
#define CITAREA_MASK				0xfffffff

/* Codec (id = 0) or preview (id = 1) path status. */
#define GT2440_CAM_REG_CISTATUS(id, _offs)	(0x64 + (id) * (0x34 + (_offs)))
#define  CISTATUS_OVFIY_STATUS			(1 << 31)
#define  CISTATUS_OVFICB_STATUS			(1 << 30)
#define  CISTATUS_OVFICR_STATUS			(1 << 29)
#define  CISTATUS_OVF_MASK			(0x7 << 29)
#define  CIPRSTATUS_OVF_MASK			(0x3 << 30)
#define  CISTATUS_VSYNC_STATUS			(1 << 28)
#define  CISTATUS_FRAMECNT_MASK			(3 << 26)
#define  CISTATUS_FRAMECNT(__reg)		(((__reg) >> 26) & 0x3)
#define  CISTATUS_WINOFSTEN_STATUS		(1 << 25)
#define  CISTATUS_IMGCPTEN_STATUS		(1 << 22)
#define  CISTATUS_IMGCPTENSC_STATUS		(1 << 21)
#define  CISTATUS_VSYNC_A_STATUS		(1 << 20)
#define  CISTATUS_FRAMEEND_STATUS		(1 << 19) /* 17 on s3c64xx */

/* Image capture enable */
#define GT2440_CAM_REG_CIIMGCPT(_offs)		(0xa0 + (_offs))
#define  CIIMGCPT_IMGCPTEN			(1 << 31)
#define  CIIMGCPT_IMGCPTEN_SC(id)		(1 << (30 - (id)))
/* Frame control: 1 - one-shot, 0 - free run */
#define  CIIMGCPT_CPT_FREN_ENABLE(id)		(1 << (25 - (id)))
#define  CIIMGCPT_CPT_FRMOD_ENABLE		(0 << 18)
#define  CIIMGCPT_CPT_FRMOD_CNT			(1 << 18)

/* Capture sequence */
#define GT2440_CAM_REG_CICPTSEQ			0xc4

/* Image effects */
#define GT2440_CAM_REG_CIIMGEFF(_offs)		(0xb0 + (_offs))
#define  CIIMGEFF_IE_ENABLE(id)			(1 << (30 + (id)))
#define  CIIMGEFF_IE_ENABLE_MASK		(3 << 30)
/* Image effect: 1 - after scaler, 0 - before scaler */
#define  CIIMGEFF_IE_AFTER_SC			(1 << 29)
#define  CIIMGEFF_FIN_MASK			(7 << 26)
#define  CIIMGEFF_FIN_BYPASS			(0 << 26)
#define  CIIMGEFF_FIN_ARBITRARY			(1 << 26)
#define  CIIMGEFF_FIN_NEGATIVE			(2 << 26)
#define  CIIMGEFF_FIN_ARTFREEZE			(3 << 26)
#define  CIIMGEFF_FIN_EMBOSSING			(4 << 26)
#define  CIIMGEFF_FIN_SILHOUETTE		(5 << 26)
#define  CIIMGEFF_PAT_CBCR_MASK			((0xff << 13) | 0xff)
#define  CIIMGEFF_PAT_CB(x)			((x) << 13)
#define  CIIMGEFF_PAT_CR(x)			(x)

/* MSCOY0SA, MSPRY0SA. Y/Cb/Cr frame start address for input DMA. */
#define GT2440_CAM_REG_MSY0SA(id)		(0xd4 + ((id) * 0x2c))
#define GT2440_CAM_REG_MSCB0SA(id)		(0xd8 + ((id) * 0x2c))
#define GT2440_CAM_REG_MSCR0SA(id)		(0xdc + ((id) * 0x2c))

/* MSCOY0END, MSCOY0END. Y/Cb/Cr frame end address for input DMA. */
#define GT2440_CAM_REG_MSY0END(id)		(0xe0 + ((id) * 0x2c))
#define GT2440_CAM_REG_MSCB0END(id)		(0xe4 + ((id) * 0x2c))
#define GT2440_CAM_REG_MSCR0END(id)		(0xe8 + ((id) * 0x2c))

/* MSPRYOFF, MSPRYOFF. Y/Cb/Cr offset. n: 0 - codec, 1 - preview. */
#define GT2440_CAM_REG_MSYOFF(id)		(0x118 + ((id) * 0x2c))
#define GT2440_CAM_REG_MSCBOFF(id)		(0x11c + ((id) * 0x2c))
#define GT2440_CAM_REG_MSCROFF(id)		(0x120 + ((id) * 0x2c))

/* Real input DMA data size. n = 0 - codec, 1 - preview. */
#define GT2440_CAM_REG_MSWIDTH(id)		(0xf8 + (id) * 0x2c)
#define  AUTOLOAD_ENABLE			(1 << 31)
#define  ADDR_CH_DIS				(1 << 30)
#define  MSHEIGHT(x)				(((x) & 0x3ff) << 16)
#define  MSWIDTH(x)				((x) & 0x3ff)

/* Input DMA control. n = 0 - codec, 1 - preview */
#define GT2440_CAM_REG_MSCTRL(id)		(0xfc + (id) * 0x2c)
#define  MSCTRL_ORDER422_M_YCBYCR		(0 << 4)
#define  MSCTRL_ORDER422_M_YCRYCB		(1 << 4)
#define  MSCTRL_ORDER422_M_CBYCRY		(2 << 4)
#define  MSCTRL_ORDER422_M_CRYCBY		(3 << 4)
/* 0 - camera, 1 - DMA */
#define  MSCTRL_SEL_DMA_CAM			(1 << 3)
#define  MSCTRL_INFORMAT_M_YCBCR420		(0 << 1)
#define  MSCTRL_INFORMAT_M_YCBCR422		(1 << 1)
#define  MSCTRL_INFORMAT_M_YCBCR422I		(2 << 1)
#define  MSCTRL_INFORMAT_M_RGB			(3 << 1)
#define  MSCTRL_ENVID_M				(1 << 0)

/* CICOSCOSY, CIPRSCOSY. Scan line Y/Cb/Cr offset. */
#define GT2440_CAM_REG_CISSY(id)			(0x12c + (id) * 0x0c)
#define GT2440_CAM_REG_CISSCB(id)		(0x130 + (id) * 0x0c)
#define GT2440_CAM_REG_CISSCR(id)		(0x134 + (id) * 0x0c)
#define GT2440_CISS_OFFS_INITIAL(x)		((x) << 16)
#define GT2440_CISS_OFFS_LINE(x)			((x) << 0)

#define GT2440_CAM_NUM_GPIOS	13





#define GT2440_CAM_DRIVER_NAME	"gt2440-cam"
#define CAM_REQ_BUFS_MIN	3
#define CAM_MAX_OUT_BUFS	4
#define CAM_MAX_PIX_WIDTH	4096
#define CAM_MAX_PIX_HEIGHT	4096
#define SCALER_MAX_RATIO	64
#define CAM_DEF_WIDTH	640
#define CAM_DEF_HEIGHT	480
#define CAM_STOP_TIMEOUT	1500 /* ms */

#define GT2440_CAMIF_IP_REV	0x20 /* 2.0 */
#define S3C6410_CAMIF_IP_REV	0x32 /* 3.2 */

/* struct camif_vp::state */

#define ST_VP_PENDING		(1 << 0)
#define ST_VP_RUNNING		(1 << 1)
#define ST_VP_STREAMING		(1 << 2)
#define ST_VP_SENSOR_STREAMING	(1 << 3)

#define ST_VP_ABORTING		(1 << 4)
#define ST_VP_OFF		(1 << 5)
#define ST_VP_LASTIRQ		(1 << 6)

#define ST_VP_CONFIG		(1 << 8)

#define CAM_SD_PAD_SINK	0
#define CAM_SD_PAD_SOURCE_C	1
#define CAM_SD_PAD_SOURCE_P	2
#define CAM_SD_PADS_NUM	3


#define V4L2_MBUS_MASTER			(1 << 0)
#define V4L2_MBUS_SLAVE				(1 << 1)
/* Which signal polarities it supports */
/* Note: in BT.656 mode HSYNC and VSYNC are unused */
#define V4L2_MBUS_HSYNC_ACTIVE_HIGH		(1 << 2)
#define V4L2_MBUS_HSYNC_ACTIVE_LOW		(1 << 3)
#define V4L2_MBUS_VSYNC_ACTIVE_HIGH		(1 << 4)
#define V4L2_MBUS_VSYNC_ACTIVE_LOW		(1 << 5)
#define V4L2_MBUS_PCLK_SAMPLE_RISING		(1 << 6)
#define V4L2_MBUS_PCLK_SAMPLE_FALLING		(1 << 7)
#define V4L2_MBUS_DATA_ACTIVE_HIGH		(1 << 8)
#define V4L2_MBUS_DATA_ACTIVE_LOW		(1 << 9)

/* Serial flags */
/* How many lanes the client can use */
#define V4L2_MBUS_CSI2_1_LANE			(1 << 0)
#define V4L2_MBUS_CSI2_2_LANE			(1 << 1)
#define V4L2_MBUS_CSI2_3_LANE			(1 << 2)
#define V4L2_MBUS_CSI2_4_LANE			(1 << 3)
/* On which channels it can send video data */
#define V4L2_MBUS_CSI2_CHANNEL_0		(1 << 4)
#define V4L2_MBUS_CSI2_CHANNEL_1		(1 << 5)
#define V4L2_MBUS_CSI2_CHANNEL_2		(1 << 6)
#define V4L2_MBUS_CSI2_CHANNEL_3		(1 << 7)
/* Does it support only continuous or also non-continuous clock mode */
#define V4L2_MBUS_CSI2_CONTINUOUS_CLOCK		(1 << 8)
#define V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK	(1 << 9)

#define V4L2_MBUS_CSI2_LANES		(V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_2_LANE | \
					 V4L2_MBUS_CSI2_3_LANE | V4L2_MBUS_CSI2_4_LANE)
#define V4L2_MBUS_CSI2_CHANNELS		(V4L2_MBUS_CSI2_CHANNEL_0 | V4L2_MBUS_CSI2_CHANNEL_1 | \
					 V4L2_MBUS_CSI2_CHANNEL_2 | V4L2_MBUS_CSI2_CHANNEL_3)








#define img_fmt_is_rgb(x) ((x) & 0x10)
#define img_fmt_is_ycbcr(x) ((x) & 0x60)

/* Possible values for struct camif_fmt::flags */
#define FMT_FL_GT2440_CODEC	(1 << 0)
#define FMT_FL_GT2440_PREVIEW	(1 << 1)
#define FMT_FL_S3C64XX		(1 << 2)


/***** plat device name *****/
#define PLAT_DEVICE_NAME	"gt2440-cam"						
								
static inline void gt2440_cam_hw_write_reg(struct gt2440_cam_info *_info,
			u32 _off, u32 _val)
{
	writel(_val, (_info)->regs+ (_off));
}
static inline u32 gt2440_cam_hw_read_reg(struct gt2440_cam_info *_info, 
	u32 _off)
{
	return readl((_info)->regs + (_off));
}


static inline void gt2440_cam_active_queue_add(struct gt2440_cam_vp *vp,
					  struct gt2440_cam_buffer *buf)
{
	list_add_tail(&buf->list, &vp->active_buf_q);
	vp->active_buffers++;
}

static inline struct gt2440_cam_buffer *gt2440_cam_active_queue_peek(
			   struct gt2440_cam_vp *vp, int index)
{
	struct gt2440_cam_buffer *tmp, *buf;
	if (WARN_ON(list_empty(&vp->active_buf_q)))
		return NULL;
	list_for_each_entry_safe(buf, tmp, &vp->active_buf_q, list) {
		if (buf->index == index) {
			list_del(&buf->list);
			vp->active_buffers--;
			return buf;
		}
	}
	return NULL;
}
static inline void gt2440_cam_pending_queue_add(struct gt2440_cam_vp *vp,
					   struct gt2440_cam_buffer *buf)
{
	list_add_tail(&buf->list, &vp->pending_buf_q);
}
static inline struct gt2440_cam_buffer *gt2440_cam_pending_queue_pop(
					struct gt2440_cam_vp *vp)
{
	struct gt2440_cam_buffer *buf = list_first_entry(&vp->pending_buf_q,
					      struct gt2440_cam_buffer, list);
	list_del(&buf->list);
	return buf;
}
static inline struct gt2440_cam_buffer *gt2440_cam_active_queue_pop(
					struct gt2440_cam_vp *vp)
{
	struct gt2440_cam_buffer *buf = list_first_entry(&vp->active_buf_q,
					      struct gt2440_cam_buffer, list);
	list_del(&buf->list);
	vp->active_buffers--;
	return buf;
}



static inline void gt2440_cam_hw_clear_pending_irq(struct gt2440_cam_vp *vp)
{
	u32 cfg =gt2440_cam_hw_read_reg(vp->info, GT2440_CAM_REG_CIGCTRL);
	cfg |= CIGCTRL_IRQ_CLR(vp->id);
	gt2440_cam_hw_write_reg(vp->info, GT2440_CAM_REG_CIGCTRL, cfg);
}
static inline u32 gt2440_cam_hw_get_status(struct gt2440_cam_vp *vp)
{	u32 cfg =gt2440_cam_hw_read_reg(vp->info, GT2440_CAM_REG_CISTATUS(vp->id,
								vp->offset));
	return cfg;
}


/***** function declare *****/
static int gt2440_cam_queue_setup(struct vb2_queue *vb2_q, 
			unsigned int *num_buffers, unsigned int *num_planes, 
			unsigned long sizes[],  void *allocators[]);
static void gt2440_cam_wait_prepare(struct vb2_queue *vb2_q);
static void gt2440_cam_wait_finish(struct vb2_queue *vb2_q);
static int gt2440_cam_buf_prepare(struct vb2_buffer *vb2_b);
static int gt2440_cam_start_streaming(struct vb2_queue *vb2_q);
static int gt2440_cam_stop_streaming(struct vb2_queue *vb2_q);
static void gt2440_cam_buf_queue(struct vb2_buffer *vb2_b);
static int gt2440_cam_enum_mbus_code(struct v4l2_subdev *v4l2_sub,
					struct v4l2_subdev_fh *fh,
					struct v4l2_subdev_mbus_code_enum *code);
static int gt2440_cam_get_fmt(struct v4l2_subdev *v4l2_sub,
				    struct v4l2_subdev_fh *fh,
				    struct v4l2_subdev_format *format);
static int gt2440_cam_set_fmt(struct v4l2_subdev *v4l2_sub,
				    struct v4l2_subdev_fh *fh,
				    struct v4l2_subdev_format *format);


static int gt2440_cam_s_ctrl(struct v4l2_ctrl *ctrl);


static int gt2440_cam_vidioc_querycap(struct file *file, void *priv,
				     struct v4l2_capability *cap);

static int gt2440_cam_vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
				     struct v4l2_fmtdesc *desc);
static int gt2440_cam_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
				  struct v4l2_format *format);
static int gt2440_cam_vidioc_s_fmt_vid_cap(struct file *file, void *priv,
				  struct v4l2_format *format);
static int gt2440_cam_vidioc_try_fmt_vid_cap(struct file *file, void *priv,
				    struct v4l2_format *format);
static int gt2440_cam_vidioc_reqbufs(struct file *file, void *priv,
			     struct v4l2_requestbuffers *req);
static int gt2440_cam_vidioc_querybuf(struct file *file, void *priv,
			      struct v4l2_buffer *buf);
static int gt2440_cam_vidioc_qbuf(struct file *file, void *priv,
			  struct v4l2_buffer *buf);
static int gt2440_cam_vidioc_dqbuf(struct file *file, void *priv,
			   struct v4l2_buffer *buf);
static int gt2440_cam_vidioc_streamon(struct file *file, void *priv,
			      enum v4l2_buf_type type);
static int gt2440_cam_vidioc_streamoff(struct file *file, void *priv,
			       enum v4l2_buf_type type);
static int gt2440_cam_vidioc_enum_input(struct file *file, void *priv,
				       struct v4l2_input *input);
static int gt2440_cam_vidioc_g_input(struct file *file, void *priv,
				    unsigned int *i);
static int gt2440_cam_vidioc_s_input(struct file *file, void *priv,
				    unsigned int i);




static unsigned int gt2440_cam_poll(struct file *file,
				   struct poll_table_struct *wait);
static int gt2440_cam_mmap(struct file *file, struct vm_area_struct *vma);

static int gt2440_cam_sensor_set_power(struct gt2440_cam_info *info, int on);

static int gt2440_cam_open(struct file *file);
static int gt2440_cam_release(struct file *file);




static int gt2440_cam_register_sensor(struct gt2440_cam_info *info);
static void gt2440_cam_unregister_sensor(struct gt2440_cam_info *info);







/***** debug  *****/
#define GT2440_CAM_DEBUG
#ifdef GT2440_CAM_DEBUG
#define dprintk printk
#else
#define dprintk(...)
#endif


#endif

